/*************
author:: libo
license:: MIT
*****************/
#include<Mesh/libcell_iterator.h>
#include<iterator/cstruct_iterator.h>
#define iterator_v lib_cell_iterator_vertices
#define iterator_f lib_cell_iterator_faces
#define iterator_c lib_cell_iterator_cells
#define iterator_edge lib_cell_iterator_edge

#define quote lib_cell_quote
iterator_v operator++(iterator_v& vv_)
{
    if(vv_.value==NULL)
    {
        vv_.it++;
    }
    else
    {
        (vv_.i)++;

    }
    return vv_;
}
iterator_v operator++(iterator_v&vv_,int)
{
    iterator_v vv=vv_;
    if(vv_.value==NULL)
    {
        vv_.it++;
    }
    else
    {
        (vv_.i)++;
    } 
    return vv;


}

template_v operator*(iterator_v &vv_)
{
    return *quote(vv_);

}
bool operator!=(const iterator_v&v_1,const iterator_v& v_2)
{
    if(v_1.value==v_2.value&&v_1.i==v_2.i&&v_1.it==v_2.it)
    {
        return false;
    }
    return true;
    
}

iterator_f operator++(iterator_f& f_)
{
    if(f_.node.value==NULL)
    {
        f_.it++;
    }
    else
    {
        f_.node--;
    }
    
    return f_;
}
iterator_f operator++(iterator_f&f_,int)
{
    iterator_f f1=f_;
    if(f_.node.value==NULL)
    {
        f_.it++;
    }
    else
    {

        (f_.node)--;
    }
    return f1;

}

template_f operator*(iterator_f&f_)
{
    return *quote(f_);
}

bool operator!=(const iterator_f& f_1,const iterator_f& f_2)
{
    if(f_1.node.value==f_2.node.value&&f_1.it==f_2.it)
    {
        return false;
    } 
    return true;
}

iterator_c operator++(iterator_c& c_)
{
    if(c_.node.value==NULL)
    {
        c_.it++;
    }
    else
    {
        c_.node++;
    }
    return c_;
}
iterator_c operator++(iterator_c &c_,int)
{
    iterator_c c_1=c_;
    if(c_.node.value==NULL)
    {
        c_.it++;
    }
    else
    {
        (c_.node)++;
    }
    return c_1;

}


template_c operator*(iterator_c&c_)
{
    return *quote(c_);
}
bool operator!=(const iterator_c& c_1,const iterator_c& c_2)
{
    if(c_1.node.value==c_2.node.value&&c_1.it==c_2.it)
    {
        return false;
    }
    return true;
}

iterator_hf operator++(iterator_hf& it)
{
    if(it.node.value==NULL)
    {
        it.it++;
    } 
    else
    {
        it.node--;
    }
    return it;
}
iterator_hf operator++(iterator_hf& it,int)
{
    iterator_hf hf_=it;
    if(it.node.value==NULL)
    {
        it.it++;
    }
    else
    {
        it.node--;
    }
    return hf_;

}

template_hf operator*(iterator_hf& it)
{
    return *quote(it);

}
bool operator!=(const iterator_hf& it1,const iterator_hf&it2)
{
    if(it1.node.value==it2.node.value&&it1.it==it2.it)
    {
        return false;
    }
    return true;
}
iterator_edge operator++(iterator_edge&ie)
{
    if(ie.f==NULL||ie.v==NULL)
    {
        ie.f=NULL;ie.v=NULL;
        return ie;
    }
    template_v* v=NULL;template_f* f=NULL;
    for(int i=0;i<ie.f->vertices_size;i++)
    {
        if(ie.f->vertices[i]!=ie.v)
        {
            v=ie.f->vertices[i];
            break;
        }
    }
    ie.v=v;
    if(v==NULL)
    {
        ie.f=NULL;
        return ie;
    }
    for(Node* nit=v->faces;nit!=NULL;nit=(Node*)(nit->Next))
    {
        if(nit->value!=ie.f)
        {
            f=(template_f*)(nit->value);
            break;
        }
    }
    ie.f=f;

    if(ie.f==ie.mark)
    {
        ie.v=NULL;
        ie.f==NULL;
    }
    return ie;
}
iterator_edge operator++(iterator_edge&ie,int)
{
    iterator_edge ie1=ie;
    if(ie.f==NULL||ie.v==NULL)
    {
        ie.f=NULL;ie.v=NULL;
        return ie1;
    }
    template_v* v=NULL;template_f* f=NULL;
    for(int i=0;i<ie.f->vertices_size;i++)
    {
        if(ie.f->vertices[i]!=ie.v)
        {
            v=ie.f->vertices[i];
            break;
        }
    }
    ie.v=v;
    if(v==NULL)
    {
        ie.f=NULL;
        return ie1;
    }
    for(Node* nit=v->faces;nit!=NULL;nit=(Node*)(nit->Next))
    {
        if(nit->value!=ie.f)
        {
            f=(template_f*)(nit->value);
            break;
        }
    }
    ie.f=f;
    if(ie.f==ie.mark)
    {
        ie.f=NULL;
        ie.v=NULL;
    }


    return ie1;

}
bool operator!=(const iterator_edge&ie1,const iterator_edge &ie2)
{
    if(ie1.v==ie2.v&&ie1.f==ie2.f)
    {
        return false;
    }

    return true;

}